home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / distutils / filelist.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  10.5 KB  |  299 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''distutils.filelist
  5.  
  6. Provides the FileList class, used for poking about the filesystem
  7. and building lists of files.
  8. '''
  9. __revision__ = '$Id: filelist.py 71281 2009-04-05 21:47:02Z tarek.ziade $'
  10. import os
  11. import string
  12. import re
  13. import fnmatch
  14. from types import *
  15. from distutils.util import convert_path
  16. from distutils.errors import DistutilsTemplateError, DistutilsInternalError
  17. from distutils import log
  18.  
  19. class FileList:
  20.     """A list of files built by on exploring the filesystem and filtered by
  21.     applying various patterns to what we find there.
  22.  
  23.     Instance attributes:
  24.       dir
  25.         directory from which files will be taken -- only used if
  26.         'allfiles' not supplied to constructor
  27.       files
  28.         list of filenames currently being built/filtered/manipulated
  29.       allfiles
  30.         complete list of files under consideration (ie. without any
  31.         filtering applied)
  32.     """
  33.     
  34.     def __init__(self, warn = None, debug_print = None):
  35.         self.allfiles = None
  36.         self.files = []
  37.  
  38.     
  39.     def set_allfiles(self, allfiles):
  40.         self.allfiles = allfiles
  41.  
  42.     
  43.     def findall(self, dir = os.curdir):
  44.         self.allfiles = findall(dir)
  45.  
  46.     
  47.     def debug_print(self, msg):
  48.         """Print 'msg' to stdout if the global DEBUG (taken from the
  49.         DISTUTILS_DEBUG environment variable) flag is true.
  50.         """
  51.         DEBUG = DEBUG
  52.         import distutils.debug
  53.         if DEBUG:
  54.             print msg
  55.         
  56.  
  57.     
  58.     def append(self, item):
  59.         self.files.append(item)
  60.  
  61.     
  62.     def extend(self, items):
  63.         self.files.extend(items)
  64.  
  65.     
  66.     def sort(self):
  67.         sortable_files = map(os.path.split, self.files)
  68.         sortable_files.sort()
  69.         self.files = []
  70.         for sort_tuple in sortable_files:
  71.             self.files.append(apply(os.path.join, sort_tuple))
  72.         
  73.  
  74.     
  75.     def remove_duplicates(self):
  76.         for i in range(len(self.files) - 1, 0, -1):
  77.             if self.files[i] == self.files[i - 1]:
  78.                 del self.files[i]
  79.                 continue
  80.         
  81.  
  82.     
  83.     def _parse_template_line(self, line):
  84.         words = string.split(line)
  85.         action = words[0]
  86.         patterns = None
  87.         dir = None
  88.         dir_pattern = None
  89.         if action in ('include', 'exclude', 'global-include', 'global-exclude'):
  90.             if len(words) < 2:
  91.                 raise DistutilsTemplateError, "'%s' expects <pattern1> <pattern2> ..." % action
  92.             len(words) < 2
  93.             patterns = map(convert_path, words[1:])
  94.         elif action in ('recursive-include', 'recursive-exclude'):
  95.             if len(words) < 3:
  96.                 raise DistutilsTemplateError, "'%s' expects <dir> <pattern1> <pattern2> ..." % action
  97.             len(words) < 3
  98.             dir = convert_path(words[1])
  99.             patterns = map(convert_path, words[2:])
  100.         elif action in ('graft', 'prune'):
  101.             if len(words) != 2:
  102.                 raise DistutilsTemplateError, "'%s' expects a single <dir_pattern>" % action
  103.             len(words) != 2
  104.             dir_pattern = convert_path(words[1])
  105.         else:
  106.             raise DistutilsTemplateError, "unknown action '%s'" % action
  107.         return (action in ('include', 'exclude', 'global-include', 'global-exclude'), patterns, dir, dir_pattern)
  108.  
  109.     
  110.     def process_template_line(self, line):
  111.         (action, patterns, dir, dir_pattern) = self._parse_template_line(line)
  112.         if action == 'include':
  113.             self.debug_print('include ' + string.join(patterns))
  114.             for pattern in patterns:
  115.                 if not self.include_pattern(pattern, anchor = 1):
  116.                     log.warn("warning: no files found matching '%s'", pattern)
  117.                     continue
  118.             
  119.         elif action == 'exclude':
  120.             self.debug_print('exclude ' + string.join(patterns))
  121.             for pattern in patterns:
  122.                 if not self.exclude_pattern(pattern, anchor = 1):
  123.                     log.warn("warning: no previously-included files found matching '%s'", pattern)
  124.                     continue
  125.             
  126.         elif action == 'global-include':
  127.             self.debug_print('global-include ' + string.join(patterns))
  128.             for pattern in patterns:
  129.                 if not self.include_pattern(pattern, anchor = 0):
  130.                     log.warn("warning: no files found matching '%s' " + 'anywhere in distribution', pattern)
  131.                     continue
  132.             
  133.         elif action == 'global-exclude':
  134.             self.debug_print('global-exclude ' + string.join(patterns))
  135.             for pattern in patterns:
  136.                 if not self.exclude_pattern(pattern, anchor = 0):
  137.                     log.warn("warning: no previously-included files matching '%s' found anywhere in distribution", pattern)
  138.                     continue
  139.             
  140.         elif action == 'recursive-include':
  141.             self.debug_print('recursive-include %s %s' % (dir, string.join(patterns)))
  142.             for pattern in patterns:
  143.                 if not self.include_pattern(pattern, prefix = dir):
  144.                     log.warn("warning: no files found matching '%s' " + "under directory '%s'", pattern, dir)
  145.                     continue
  146.             
  147.         elif action == 'recursive-exclude':
  148.             self.debug_print('recursive-exclude %s %s' % (dir, string.join(patterns)))
  149.             for pattern in patterns:
  150.                 if not self.exclude_pattern(pattern, prefix = dir):
  151.                     log.warn("warning: no previously-included files matching '%s' found under directory '%s'", pattern, dir)
  152.                     continue
  153.             
  154.         elif action == 'graft':
  155.             self.debug_print('graft ' + dir_pattern)
  156.             if not self.include_pattern(None, prefix = dir_pattern):
  157.                 log.warn("warning: no directories found matching '%s'", dir_pattern)
  158.             
  159.         elif action == 'prune':
  160.             self.debug_print('prune ' + dir_pattern)
  161.             if not self.exclude_pattern(None, prefix = dir_pattern):
  162.                 log.warn('no previously-included directories found ' + "matching '%s'", dir_pattern)
  163.             
  164.         else:
  165.             raise DistutilsInternalError, "this cannot happen: invalid action '%s'" % action
  166.         return action == 'include'
  167.  
  168.     
  169.     def include_pattern(self, pattern, anchor = 1, prefix = None, is_regex = 0):
  170.         '''Select strings (presumably filenames) from \'self.files\' that
  171.         match \'pattern\', a Unix-style wildcard (glob) pattern.  Patterns
  172.         are not quite the same as implemented by the \'fnmatch\' module: \'*\'
  173.         and \'?\'  match non-special characters, where "special" is platform-
  174.         dependent: slash on Unix; colon, slash, and backslash on
  175.         DOS/Windows; and colon on Mac OS.
  176.  
  177.         If \'anchor\' is true (the default), then the pattern match is more
  178.         stringent: "*.py" will match "foo.py" but not "foo/bar.py".  If
  179.         \'anchor\' is false, both of these will match.
  180.  
  181.         If \'prefix\' is supplied, then only filenames starting with \'prefix\'
  182.         (itself a pattern) and ending with \'pattern\', with anything in between
  183.         them, will match.  \'anchor\' is ignored in this case.
  184.  
  185.         If \'is_regex\' is true, \'anchor\' and \'prefix\' are ignored, and
  186.         \'pattern\' is assumed to be either a string containing a regex or a
  187.         regex object -- no translation is done, the regex is just compiled
  188.         and used as-is.
  189.  
  190.         Selected strings will be added to self.files.
  191.  
  192.         Return 1 if files are found.
  193.         '''
  194.         files_found = 0
  195.         pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
  196.         self.debug_print("include_pattern: applying regex r'%s'" % pattern_re.pattern)
  197.         if self.allfiles is None:
  198.             self.findall()
  199.         
  200.         for name in self.allfiles:
  201.             if pattern_re.search(name):
  202.                 self.debug_print(' adding ' + name)
  203.                 self.files.append(name)
  204.                 files_found = 1
  205.                 continue
  206.         
  207.         return files_found
  208.  
  209.     
  210.     def exclude_pattern(self, pattern, anchor = 1, prefix = None, is_regex = 0):
  211.         """Remove strings (presumably filenames) from 'files' that match
  212.         'pattern'.  Other parameters are the same as for
  213.         'include_pattern()', above.
  214.         The list 'self.files' is modified in place.
  215.         Return 1 if files are found.
  216.         """
  217.         files_found = 0
  218.         pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
  219.         self.debug_print("exclude_pattern: applying regex r'%s'" % pattern_re.pattern)
  220.         for i in range(len(self.files) - 1, -1, -1):
  221.             if pattern_re.search(self.files[i]):
  222.                 self.debug_print(' removing ' + self.files[i])
  223.                 del self.files[i]
  224.                 files_found = 1
  225.                 continue
  226.         
  227.         return files_found
  228.  
  229.  
  230.  
  231. def findall(dir = os.curdir):
  232.     """Find all files under 'dir' and return the list of full filenames
  233.     (relative to 'dir').
  234.     """
  235.     ST_MODE = ST_MODE
  236.     S_ISREG = S_ISREG
  237.     S_ISDIR = S_ISDIR
  238.     S_ISLNK = S_ISLNK
  239.     import stat
  240.     list = []
  241.     stack = [
  242.         dir]
  243.     pop = stack.pop
  244.     push = stack.append
  245.     while stack:
  246.         dir = pop()
  247.         names = os.listdir(dir)
  248.         for name in names:
  249.             if dir != os.curdir:
  250.                 fullname = os.path.join(dir, name)
  251.             else:
  252.                 fullname = name
  253.             stat = os.stat(fullname)
  254.             mode = stat[ST_MODE]
  255.             if S_ISREG(mode):
  256.                 list.append(fullname)
  257.                 continue
  258.             if S_ISDIR(mode) and not S_ISLNK(mode):
  259.                 push(fullname)
  260.                 continue
  261.         
  262.     return list
  263.  
  264.  
  265. def glob_to_re(pattern):
  266.     '''Translate a shell-like glob pattern to a regular expression; return
  267.     a string containing the regex.  Differs from \'fnmatch.translate()\' in
  268.     that \'*\' does not match "special characters" (which are
  269.     platform-specific).
  270.     '''
  271.     pattern_re = fnmatch.translate(pattern)
  272.     pattern_re = re.sub('((?<!\\\\)(\\\\\\\\)*)\\.', '\\1[^/]', pattern_re)
  273.     return pattern_re
  274.  
  275.  
  276. def translate_pattern(pattern, anchor = 1, prefix = None, is_regex = 0):
  277.     """Translate a shell-like wildcard pattern to a compiled regular
  278.     expression.  Return the compiled regex.  If 'is_regex' true,
  279.     then 'pattern' is directly compiled to a regex (if it's a string)
  280.     or just returned as-is (assumes it's a regex object).
  281.     """
  282.     if is_regex:
  283.         if type(pattern) is StringType:
  284.             return re.compile(pattern)
  285.         return pattern
  286.     is_regex
  287.     if pattern:
  288.         pattern_re = glob_to_re(pattern)
  289.     else:
  290.         pattern_re = ''
  291.     if prefix is not None:
  292.         prefix_re = glob_to_re(prefix)[0:-1]
  293.         pattern_re = '^' + os.path.join(prefix_re, '.*' + pattern_re)
  294.     elif anchor:
  295.         pattern_re = '^' + pattern_re
  296.     
  297.     return re.compile(pattern_re)
  298.  
  299.